package net.qhzw.vip.qiyu.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import net.qhzw.vip.qiyu.component.ServerConfig;
import net.qhzw.vip.qiyu.entity.*;
import net.qhzw.vip.qiyu.handler.ApiException;
import net.qhzw.vip.qiyu.handler.MyException;
import net.qhzw.vip.qiyu.mapper.DtsUserMapper;
import net.qhzw.vip.qiyu.mapper.SysUserMapper;
import net.qhzw.vip.qiyu.model.*;
import net.qhzw.vip.qiyu.result.ResultCode;
import net.qhzw.vip.qiyu.service.*;
import net.qhzw.vip.qiyu.util.BeanMapUtils;
import net.qhzw.vip.qiyu.util.JwtToken;
import net.qhzw.vip.qiyu.util.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    private DtsUserService dtsUserService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private RestTemplate restTemplate;

    @Value("${basic.token:Basic Y29pbi1hcGk6Y29pbi1zZWNyZXQ=}")
    private String basicToken;

    @Autowired
    private ServerConfig serverConfig;

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysPrivilegeService sysPrivilegeService;

    @Autowired
    private GuaranteeCompanyService guaranteeCompanyService;

    @Autowired
    private GuaranteeSiteService guaranteeSiteService;

    @Autowired
    private GuaranteeUserService guaranteeUserService;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private DtsUserMapper dtsUserMapper;

    /***
     * 用户登录
     * @param param
     * @return
     */
    @Override
    public LoginUser userLogin(LoginForm param) {
        log.info("用户{}开始登录", param.getUsername());
        JwtToken jwtToken = sendLogin(param);
        log.info("远程调用成功,结果为", JSON.toJSONString(jwtToken, true));
        /*LoginUser loginUser = new LoginUser(param.getUsername(),
                "100",
                jwtToken.getExpiresIn(),
                jwtToken.getTokenType() + " " + jwtToken.getAccessToken(),
                jwtToken.getRefreshToken());*/
        LoginUser loginUser = new LoginUser();
        log.info("微信登录成功, 结果为:【{}】", JSON.toJSONString(loginUser, true));
        return loginUser;
    }


    /***
     * 分页查询后台管理人员
     * @param page
     * @param keyword
     * @return
     */
    @Override
    public Page<SysUser> findByPage(Page<SysUser> page, String keyword, Long shopId) {
        page.addOrder(OrderItem.desc("created"));
        Page<SysUser> sysUserPage = page(page, new LambdaQueryWrapper<SysUser>()
                .eq(shopId != 1, SysUser::getShopId, shopId)
                .like(!StringUtils.isEmpty(keyword), SysUser::getUsername, keyword)
                .or()
                .eq(!StringUtils.isEmpty(keyword), SysUser::getFullname, keyword)
        );
        List<SysUser> records = sysUserPage.getRecords();
        if (!CollectionUtils.isEmpty(records)) {
            Map<Long, SysRole> sysRoleMap = sysRoleService
                    .list().stream()
                    .collect(Collectors
                            .toMap(sysRole -> sysRole.getId(), sysRole -> sysRole));
            for (SysUser record : records) {
                if (record.getCompanyId() != null) {
                    String companyName = guaranteeCompanyService.getNameById(record.getCompanyId());
                    record.setCompanyName(companyName);
                }
                for (Map.Entry<Long, SysRole> entry : sysRoleMap.entrySet()) {
                    if (!StringUtils.isEmpty(record.getRoleId()) && record.getRoleId().equals(entry.getKey())) {
                        record.setRoleName(entry.getValue().getName());
                    }
                }
            }
        }
        return sysUserPage;
    }

    /***
     * 后台用户登成功返回的权限菜单
     * @param userId
     * @return
     */
    @Override
    public LoginSysUser getLoginSysUser(String userId) {
        SysUser sysUser = sysUserService.getById(userId);
        if (sysUser == null) {
            throw new MyException(ResultCode.PARAMERR);
        }
        boolean superAdmin = sysRoleService.isSuperAdmin(Long.valueOf(userId));
        List<SysMenu> sysMenuList = null;
        List<SysPrivilege> sysPrivileges = null;
        if (superAdmin) {
            sysMenuList = sysMenuService.list();
            sysPrivileges = sysPrivilegeService.list();
        } else {
            //根据userId查询菜单数据
            sysMenuList = sysMenuService.getMenusByUserId(Long.valueOf(userId));
            sysPrivileges = sysPrivilegeService.getPrivilegeByUserId(Long.valueOf(userId));
        }
        List<String> menus = new ArrayList<>();
        if (!CollectionUtils.isEmpty(sysMenuList)) {
            sysMenuList.forEach(data -> {
                menus.add(data.getName());
            });
        }
        List<String> privileges = new ArrayList<>();
        if (!CollectionUtils.isEmpty(sysPrivileges)) {
            sysPrivileges.forEach(data -> {
                privileges.add(data.getName());
            });
        }
        LoginSysUser loginSysUser = new LoginSysUser();
        loginSysUser.setSysUser(sysUser);
        loginSysUser.setMenus(menus);
        loginSysUser.setPermissions(privileges);
        return loginSysUser;
    }

    /***
     * 添加系统用户
     * @param sysUser
     * @return
     */
    @Override
    public boolean addSysUser(Long userId, SysUser sysUser) {
        SysUser user = getById(userId);
        if (user == null || user.getParentId() != 0) {
            throw new ApiException(user.getFullname() + "用户没有添加权限, 请使用管理员账号添加用户!");
        }
        sysUser.setId(IdWorker.getId());
        sysUser.setParentId(userId);
        sysUser.setShopId(SecurityUtils.getLoginUser().getShopId());
        sysUser.setStatus((byte) 1);
        sysUser.setCreateBy(SecurityUtils.getUserId());
        sysUser.setCreated(new Date());
        sysUser.setLastUpdateTime(new Date());
        sysUser.setPassword(new BCryptPasswordEncoder().encode(sysUser.getPassword()));
        return save(sysUser);
    }

    /***
     * 修改系统用户
     * @param sysUser
     * @return
     */
    @Override
    public boolean updateSysUser(SysUser sysUser) {
        log.info("修改系统用户: {}", JSON.toJSONString(sysUser, true));
        sysUser.setLastUpdateTime(new Date());
        sysUser.setModifyBy(SecurityUtils.getUserId());
        int update = sysUserMapper.updateByPrimaryKeySelective(sysUser);
        if (update > 0) {
            return true;
        }
        return false;
    }

    /***
     * 个人信息修改
     * @param modifyUserForm
     * @return
     */
    @Override
    public boolean updateUserInfo(ModifyUserForm modifyUserForm) {
        SysUser sysUser = getById(modifyUserForm.getId());
        if (sysUser == null) {
            throw new MyException(ResultCode.PARAMERR);
        }
        if (!new BCryptPasswordEncoder().matches(modifyUserForm.getOldPassword(), sysUser.getPassword())) {
            throw new MyException(500, "原密码错误");
        }
        SysUser sysUserdb = updateUser(modifyUserForm);
        return updateById(sysUserdb);
    }

    /***
     * 根据角色id查询角色名称
     * @param roleId
     * @return
     */
    @Override
    public String getRoleNameById(Long roleId) {
        return sysRoleService.getRoleNameById(roleId);
    }

    /***
     * 根据担保公司id查询名称
     * @param companyId
     * @return
     */
    @Override
    public String findCompanyNameById(Long companyId) {
        if (companyId == 1L) {
            return "全部";
        }
        return guaranteeCompanyService.getNameById(companyId);
    }

    /***
     * 根据userId获取权限数据
     * @param userId
     * @return
     */
    @Override
    public List<String> getPermissions(Long userId) {
        return sysMenuService.getPermissions(userId);
    }

    private SysUser updateUser(ModifyUserForm modifyUserForm) {
        SysUser sysUser = new SysUser();
        sysUser.setId(modifyUserForm.getId());
        sysUser.setPassword(new BCryptPasswordEncoder().encode(modifyUserForm.getPassword()));
        sysUser.setFullname(modifyUserForm.getFullname());
        sysUser.setMobile(modifyUserForm.getMobile());
        sysUser.setEmail(modifyUserForm.getEmail());
        sysUser.setStatus((byte) 1);
        sysUser.setLastUpdateTime(new Date());
        sysUser.setModifyBy(SecurityUtils.getUserId());
        return sysUser;
    }

    /***
     * 社区人员登录
     * @param param
     * @return
     */
    private LoginUser loginUser(LoginForm param) {
        DtsUser dtsUser = dtsUserService.getOne(new LambdaQueryWrapper<DtsUser>()
                .eq(DtsUser::getMobile, param.getUsername())
                .or()
                .eq(DtsUser::getUsername, param.getUsername())
        );
        if (dtsUser == null) {
            throw new MyException(500, "账号不存在,请联系管理员");
        }
        if (dtsUser.getStatus().intValue() != 1) {
            throw new MyException(500, "账号已锁定,请联系管理员");
        }
        if (!new BCryptPasswordEncoder().matches(param.getPassword(), dtsUser.getPassword())) {
            throw new MyException(500, "密码不正确");
        }
        Map<String, Object> stringObjectMap = BeanMapUtils.beanToMap(dtsUser);
        LoginUser loginUser = new LoginUser();
        loginUser.setUserId(String.valueOf(dtsUser.getId()));
        loginUser.setUsername(dtsUser.getMobile());
        //String jwt = JwtUtils.createJwt(String.valueOf(dtsUser.getId()), dtsUser.getMobile(), stringObjectMap);
        String jwt = "";

        loginUser.setAccess_token(jwt);
        loginUser.setExpire(3600000L);
        log.info("【社区登录】,响应结果:{}", JSONObject.toJSONString(loginUser, true));
        return loginUser;
    }

    /***
     * 获取token
     * @param param
     * @return
     */
    private JwtToken sendLogin(LoginForm param) {
        String grantType = "password";
        String serverName = serverConfig.getUrl();
        String url = serverName + "/oauth/token?grant_type=%s&password=%s&username=%s&login_type=%s";
        String formatUrl = String.format(url, grantType, param.getPassword(), param.getUsername(), param.getLoginType());
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", basicToken);
        HttpEntity<String> request = new HttpEntity<>(headers);
        JwtToken jwtToken = restTemplate.postForObject(formatUrl, request, JwtToken.class);
        return jwtToken;
    }


    /***
     * 分页查询担保站点风险预警
     * @param query
     * @return
     */
    @Override
    public Map<String, Object> getWarningByPage(Long shopId, WarningQuery query) {
        Map<String, Object> result = new HashMap<>();
        Long userId = SecurityUtils.getUserId();
        if (query != null && query.getUserId() != null) {
            userId = query.getUserId();
        }
        SysUser sysUser = sysUserService.getById(userId);
        if (sysUser == null) {
            throw new ApiException("用户信息已过期，请重新登录");
        }
        //担保公司ID 1查询全部
        Long companyId = sysUser.getCompanyId();
        List<GuaranteeSite> guaranteeSiteList = null;
        if (1 == companyId) {
            guaranteeSiteList = guaranteeSiteService.list(null);
        } else {
            guaranteeSiteList = guaranteeSiteService.getByCompanyId(companyId);
        }

        int total = 0;
        int count = 0;
        List<SysWarningVo> records = new ArrayList<>();
        if (!CollectionUtils.isEmpty(guaranteeSiteList)) {
            List<Long> siteIds = guaranteeSiteList.stream().map(GuaranteeSite::getId).collect(Collectors.toList());
            List<GuaranteeUser> guaranteeUsers = null;
            //查询站点下的用户
            if (!CollectionUtils.isEmpty(siteIds)) {
                guaranteeUsers = guaranteeUserService.list(new LambdaQueryWrapper<GuaranteeUser>()
                        .eq(shopId != 1, GuaranteeUser::getShopId, shopId)
                        .in(GuaranteeUser::getSiteId, siteIds));
            }
            List<SysWarningVo> sysWarningVos = new ArrayList<>();
            PageHelper.startPage(query.getCurrent(), query.getSize());
            //担保站点下的人员身份证号
            List<String> idCards = guaranteeUsers.stream().map(GuaranteeUser::getIdCard).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(idCards)) {
                query.setIdCards(idCards);
                query.setShopId(shopId);
                sysWarningVos = guaranteeSiteService.getWarning(query);
                count = guaranteeSiteService.getWarningCount(query);
            }
            PageInfo<SysWarningVo> pageInfo = new PageInfo<>(sysWarningVos);
            total = (int) pageInfo.getTotal();
            records = pageInfo.getList();
        }
        result.put("total", total);
        result.put("records", records);
        result.put("count", count);
        return result;

    }

    /***
     * 分页查询骑遇风险预警
     * @param query
     * @return
     */
    @Override
    public Map<String, Object> findByPageQY(WarningQuery query, Long shopId) {
        query.setShopId(shopId);
        Long userId = SecurityUtils.getUserId();
        SysUser sysUser = sysUserService.getById(userId);
        Long communityId = sysUser.getCommunityId();
        if (communityId != 1){
            query.setCommunityId(communityId);
        }
        PageHelper.startPage(query.getCurrent(), query.getSize());
        List<SysWarningVo> sysWarningVos = guaranteeSiteService.getWarning(query);
        Map<String, Object> result = new HashMap<>();
        PageInfo<SysWarningVo> pageInfo = new PageInfo<>(sysWarningVos);
        result.put("total", (int) pageInfo.getTotal());
        result.put("records", pageInfo.getList());
        return result;
    }

    @Override
    public SysUser getUserByUsername(String username) {
        List<SysUser> list = list(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUsername, username));
        if (!CollectionUtils.isEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public boolean updateStatus(Long shopId, Byte status) {
        dtsUserMapper.updateStatus(shopId, status);
        sysUserMapper.updateStatus(shopId, status);
        return true;
    }

    @Override
    public SysRole getRoleById(Long roleId) {
        return sysRoleService.getById(roleId);
    }



}
